package xiongwei.jiang.util;

import org.dom4j.*;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 自定义 xml 工具类
 *
 * @author 天之蓝
 */
public class XmlUtils {
    /**
     * xml 转 {@link Map}
     *
     * @param xmlStr xml 字符串
     * @return {@link Map}
     * @throws DocumentException 异常
     * @author 天之蓝
     */
    public static Map<String, Object> xml2Map(String xmlStr) throws DocumentException {
        Map<String, Object> map = new LinkedHashMap<>();
        element2Map(DocumentHelper.parseText(xmlStr).getRootElement(), map);
        return map;
    }

    /**
     * {@link Element} 转 {@link Map}
     *
     * @param rootElement 根节点
     * @param map         载体
     * @author 天之蓝
     * @see <a href="https://blog.csdn.net/lmb55/article/details/53468660/">参考链接</a>
     */
    public static void element2Map(Element rootElement, Map<String, Object> map) {
        // 获取当前节点的子节点
        List<Element> elementList = rootElement.elements();
        if (elementList.size() == 0) {
            // 当前节点是叶子节点，直接取值
            map.put(rootElement.getName(), rootElement.getText());
        } else if (elementList.size() == 1) {
            // 当前节点只有一个子节点，继续递归
            Map<String, Object> tempMap = new LinkedHashMap<>();
            element2Map(elementList.get(0), tempMap);
            map.put(rootElement.getName(), tempMap);
        } else {
            // 当前节点有多个子节点，需要判断同名节点
            elementList.stream().map(Node::getName).forEach(name -> {
                List<Element> sameElementList = rootElement.elements(new QName(name, elementList.get(0).getNamespace()));
                if (sameElementList.size() > 1) {
                    // 同名节点大于一，引入集合
                    List<Map<String, Object>> tempList = new ArrayList<>();
                    sameElementList.forEach(element -> {
                        Map<String, Object> tempMap = new LinkedHashMap<>();
                        element2Map(element, tempMap);
                        tempList.add(tempMap);
                    });
                    map.put(name, tempList);
                } else {
                    // 同名节点不大于一，继续递归
                    Map<String, Object> tempMap = new LinkedHashMap<>();
                    element2Map(sameElementList.get(0), tempMap);
                    map.put(name, tempMap);
                }
            });
        }
    }
}
